<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Dreamwork SSHD-Server</title>
    <link rel='stylesheet' type="text/css" charset='utf-8' href="highlight-js/styles/darcula.css" />
    <link rel='stylesheet' type='text/css' charset='utf-8' href="css/doc.css" />

    <script type="text/javascript" charset="utf-8" src="https://cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script>
    <script type="text/javascript" charset="utf-8" src="highlight-js/highlight.pack.js"></script>
</head>
<body>
    <h2>Dreamwork SSHD-Server</h2>
    <h3>简介</h3>
    使用 apache sshd 框架，提供一个可用的 sshd 服务器端半成品。快速开发基于 ssh 的 CLI应用程序。
    <h3>软件架构</h3>
    <ul>
        <li>底层采用 <span class='code-snip'>apache sshd</span> 框架来提供 <span class='code-snip'>SSH</span> 网络服务。</li>
        <li>内置一个实现了
            <ul>
                <li>RFC 318 (TELNET)</li>
                <li>RFC 854 – RFC 861 (TELNET sub-options)</li>
                <li>RFC 1073 (TELNET Window Size)</li>
            </ul>
            telnet协议栈的 java 实现
        </li>
        <li>扩展 <span class='code-snip'>org.dreamwork.telnet.command.Command</span> 以快速开发命令来实现功能</li>
    </ul>
    <h3>使用说明</h3>
    <h4>最简单的例子</h4>
    <pre><code class="java">
package org.dreamwork.sshd.example;

import org.dreamwork.config.IConfiguration;
import org.dreamwork.config.PropertyConfiguration;
import org.dreamwork.network.sshd.Sshd;

import java.util.Properties;

public class BasicSshdApplication {
    public static void main (String[] args) throws Exception {
        IConfiguration conf = new PropertyConfiguration (new Properties ());

        Sshd sshd = new Sshd (conf);
        sshd.init (null);
        sshd.bind ();
    }
}
    </code></pre>
    然后通过命令 <span class="code-snip">ssh -p 50022 root@127.0.0.1</span>来登录服务，
    root的默认密码是<span class='code-snip'>123456</span>。您可以在登录到sshd服务后使用
    <span class='code-snip'>passwd</span>命令来修改root的密码。
    <h4>配置 sshd 服务</h4>
    <ul>
        <li>sshd 服务默认监听 <span class='code-snip'>50022</span> 端口</li>
        <li>ca 文件的默认存储位置是 ${user.home}/.ssh-server/known-hosts</li>
        <li>sqlite 数据库文件的默认存储位置是 ${user.home}/.ssh-server/database.db</li>
    </ul>
    您可以通过配置来修改这些参数
    <ul>
        <li>键值 <span class='code-snip'>service.sshd.port</span> 用来修改监听端口</li>
        <li>键值 <span class='code-snip'>service.sshd.cert.file</span> 用来修改 ca 文件的存放路径</li>
        <li>键值 <span class='code-snip'>database.file</span> 用来修改 sqlite 数据库文件的存放路径</li>
        <li>键值 <span class='code-snip'>default.root.password</span> 用来修改默认的root密码</li>
    </ul>
    以上所有键值都可通过添加系统属性来覆盖默认值

    <h4>内置数据库</h4>
    <p>
        <span class='code-snip'>dreamwork sshd</span> 采用数据库来存储 用户数据 及 系统配置参数
    </p>
    <p>
        <span class='code-snip'>org.dreamwork.network.sshd.Sshd</span> 通过 <span class='code-snip'>init (IDatabase)</span> 
        方法传入一个数据库对象，当该方法传参为 <span class='code-snip'>null</span> 时，内部将创建一个 sqlite3 文件数据库。
        当您希望 sshd-server 和您的应用共用一个数据库时，<span class='code-snip'>init</span>方法的参数必须是一个
         <strong>非空</strong> 的数据库对象。
    </p>

    <h3>命令</h3>
    命令为<span class='code-snip'>sshd-server</span>提供一组特定功能的人机接口，通过在 
    <span class='code-snip'>org.dreamwork.network.sshd.Sshd</span>上注册 
    <span class='code-snip'>org.dreamwork.telnet.command.Command</span>的实现类来提供服务。
    <h4>内置命令</h4>
    在上面的基础实现中，<span class='code-snip'>sshd-server</span> 内置了一组命令，
    您可以登陆服务后通过命令 <span class='code-snip'>help</span>来查看：
    <pre><code class="shell">
console> help
clear            clear the screen and home cursor
echo             shows something
env              show environment
exit             alias for command 'quit'
help        h    show this help list
history          show history
passwd           change current or spec user's password
quit        q    exit
set              setting console env
shutdown         shutdown the sshd server
unset            unset a console env
user             user management
    </code></pre>
    <h4>扩展自定义命令</h4>
    通过扩展 <span class='code-snip'>org.dreamwork.telnet.command.Command</span>抽象类来自定义命令。
    <h5>一个简单的自定义命令</h5>
    我们来实现一个简单的命令：<span class='code-snip'>datetime</span>，来实现显示当前时间
    <pre><code class="java">
package org.dreamwork.sshd.example;

import org.dreamwork.telnet.Console;
import org.dreamwork.telnet.command.Command;

import java.io.IOException;
import java.text.SimpleDateFormat;

public class DateTimeCommand extends Command {
    private SimpleDateFormat sdf = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss");
    public DateTimeCommand () {
        super ("datetime", null, "show current date time");
    }

    /**
     * 执行命令
     *
     * @param console 当前控制台
     * @throws IOException io exception
     */
    @Override
    public void perform (Console console) throws IOException {
        console.println (sdf.format (System.currentTimeMillis ()));
    }
}
    </code></pre>
    <table class="method-list">
        <tr>
            <td class="method-def" colspan="2">public Command (String name, String alias, String description)</td>
        </tr>
        <tr><td class="param-name">name</td><td class="param-desc">指定命令的名称，以后在控制台输入的主命令就是这个</td></tr>
        <tr><td class="param-name">alias</td><td>命令的别名，可以为命令提供一个简短的别名</td></tr>
        <tr><td class="param-name">description</td><td>命令的简短描述，内置命令<span class='code-snip'>help</span>将使用这个描述</td></tr>
        <tr>
            <td class="method-def" colspan="2">public void perform (Console console) throws IOException</td>
        </tr>
        <tr><td class="param-name">console</td><td>即控制台对象，可以打印命令处理结果</td></tr>
    </table>
    现在，我们可以将这个命令注册到<span class='code-snip'>sshd-server</span>中了
    <pre><code class="java">
public class BasicSshdApplication {
    public static void main (String[] args) throws Exception {
        IConfiguration conf = new PropertyConfiguration (new Properties ());

        Sshd sshd = new Sshd (conf);
        sshd.init (null);

        // 注册 DateTimeCommand
        sshd.registerCommands (new DateTimeCommand ());

        sshd.bind ();
    }
}
    </code></pre>
    再次启动程序，并使用 ssh 命令登录到付，键入 help 命令，查看
    <pre><code class="shell">
console> h
clear            clear the screen and home cursor
<strong>datetime         show current date time</strong>
echo             shows something
env              show environment
exit             alias for command 'quit'
help        h    show this help list
history          show history
passwd           change current or spec user's password
quit        q    exit
set              setting console env
shutdown         shutdown the sshd server
unset            unset a console env
user             user management
    </code></pre>
    可以发现多了一个命令 <span class='code-snip'>datetime</span>，执行命令
    <pre><code class="shell">
console> datetime
2020-02-25 19:37:41
console>
    </code></pre>
    <h3>深入<span class='code-snip'>sshd-server</span>及<span class='code-snip'>Command</span></h3>
    更高级/深入的内容请参见 "<a href="user-guide.html">sshd-server 使用手册</a>"
<script>hljs.initHighlightingOnLoad();</script>
</body>
</html>